import XEUtils from 'xe-utils';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useSystemStore, useSettingStore } from '@/stores/modules';
import { AuthUtils, CryptoUtils, ResponseUtils } from '@/utils';
import { REQ_HEADER_KEY } from '@/utils/http/cfg/http-config';
import { NextLoading } from '/@/utils/loading';

/**
 * 默认的请求拦截处理方法
 * @param {Object} config 请求信息
 * @returns Object 配置信息
 */
export function reqResolve(config) {
	// 添加防重放的随机数
	config.headers['t'] = +new Date();
	// 验证token是否存在，并携带请求头
	const accessToken = AuthUtils.accessToken.get();
	if (!XEUtils.isEmpty(accessToken)) {
		config.headers[REQ_HEADER_KEY] = accessToken;
	}
	return config;
}
// 需要加密的请求方式
const encMethods = ['post'];
// 加密的白名单请求（不需要加密的请求）
const encWhiteUrls = [
	'/login',
	'/sms/login',
	'/sso/login',
	'/pubAgency/importExcelForPubagencyInfo', 
	'/proResApply/parse'
];
/**
 * 设计加密的请求拦截处理方法
 * @param {Object} config 请求信息
 * @returns Object 配置信息
 */
export function reqResolveByEncrypt(config) {
	// 系统配置是否开启了加密
	const encryptOpen = useSettingStore().encryptOpen;
	const { method, url } = config;
	if (encryptOpen && encMethods.includes(method.toLowerCase()) && !encWhiteUrls.includes(url.toLowerCase())) {
		if (config.data) {
			config.headers['content-type'] = 'application/json;charset=UTF-8';
			config.data = CryptoUtils.encryptValue(config.data);
		}
	}
	return config;
}
/**
 * 默认的请求拦截处理错误方法
 * @param {Object} error 错误信息
 * @returns Object 配置信息
 */
export function reqReject(error) {
	console.error(error);
	return Promise.reject(error);
}
/**
 * 默认响应拦截
 *
 * @param {Object} response 请求响应对象
 * @returns function
 */
export const resResolve = async (response) => {
	// 设置刷新token
	const refreshToken = response.headers['refresh-token'];
	AuthUtils.accessToken.set(refreshToken);
	// 处理响应数据
	let responseResult = null;
	const responseData = response.data;
	responseResult = responseData;

	// 校验blob类型数据，如果返回code不为200时，需要停止响应
	if (response.config.responseType && response.config.responseType === 'blob') {
		if (response.data.type.includes('application/json')) {
			const execute = () => {
				return new Promise(resolve => {
					const reader = new FileReader()
					reader.readAsText(response.data, 'utf-8')
					reader.onload = () => {
						let result = null
						try {
							result = JSON.parse(reader.result);
						} catch(err) {
							result = response.data
						}
						resolve(result)
					}
				})
			}
			const result = await execute()
			if (result && result.code) {
				return result
			} else {
				return responseResult
			}
		}
	}

	// 判断是否为加密数据
	if (ResponseUtils.checkIsEncrypted(responseData)) {
		responseResult = CryptoUtils.decryptValue(responseData);
	} else {
		responseResult = responseData;
	}
	// 校验是否登录
	if ((responseResult && !ResponseUtils.checkIsLogin(responseResult.code)) || !responseResult) {
		console.error('response interceptor responseResult is null', responseResult)
		useSystemStore().signOut(true);
	}
	// 校验license，通过配置文件控制是否校验
	const openLicenseCheck = useSettingStore().openLicenseCheck
	if (openLicenseCheck && responseResult && !ResponseUtils.checkLicenseDone(responseResult.code)) {
		NextLoading.done();
		const elememts = document.querySelectorAll('.el-overlay .license-confirm')
		if (elememts.length === 0) {
			useSystemStore().clearAllCache()
			ElMessageBox({
				closeOnClickModal: false,
				closeOnPressEscape: false,
				title: '提示',
				message: responseResult.msg,
				showClose: false,
				customClass: 'rk-message-box-confirm license-confirm',
				showCancelButton: false,
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				buttonSize: 'default',
			}).then(async () => {
				// 后端退出登录
				await useSystemStore().signOut(true);
			}).catch(() => {
			});
		}
	}
	return responseResult;
}
/**
 * blob请求方式响应拦截
 *
 * @param {Object} response 请求响应对象
 * @returns function
 */
export const blobResResolve = (response) =>  {
	// 设置刷新token
	const refreshToken = response.headers['refresh-token'];
	AuthUtils.accessToken.set(refreshToken);
	// 处理响应数据
	let responseResult = response;
	if (responseResult && !ResponseUtils.checkIsLogin(responseResult.code)) {
		useSystemStore().signOut(true);
	}
	return responseResult;
}

export function resReject(error) {
	if (isReqTimeout(error)) {
		console.error('resReject', '请求超时，请稍后重试！');
	}
	return Promise.reject(error);
}

/**
 * 请求是否超时
 *
 * @param {Object} error 错误信息
 * @returns {Boolean} true - 请求超时 false-请求未超时
 */
const errorCodesList = ['ECONNABORTED'];
function isReqTimeout(error) {
	return errorCodesList.includes(error.code) || error.message === 'Network Error' || error.message.includes('timeout');
}
